﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.ServiceModel.Syndication;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Threading;
using YAWD.BL.Services;
using YAWD.Data;
using YAWD.Properties;
using YAWD.UserControls;
using YAWD.Utils;
using YAWD.Windows;

namespace YAWD
{
    public partial class MainWindow
    {
        private WindowState _currentWindowState = WindowState.Normal;

        private readonly BackgroundWorker _backgroundWorker = new BackgroundWorker();
        private readonly BackgroundWorker _backgroundCount = new BackgroundWorker();

        private readonly DispatcherTimer _downloadTimer = new DispatcherTimer();
        private SyndicationItem _objNewVersion;
        private bool _isClose;
        private KeyboardHook _keyBoardHook;
        private bool _showDonateMessage;
        private const string StartUpKeyName = @"YAWD";
        News _news;

        public MainWindow()
        {
            InitializeComponent();

            _backgroundWorker.DoWork += _backgroundWorker_DoWork;
            _backgroundWorker.RunWorkerCompleted += _backgroundWorker_RunWorkerCompleted;
            _backgroundWorker.RunWorkerAsync();

            _backgroundCount.DoWork += _backgroundCount_DoWork;
            _backgroundCount.RunWorkerCompleted += _backgroundCount_RunWorkerCompleted;

            _keyBoardHook = new KeyboardHook(ModifierKeys.Windows, System.Windows.Forms.Keys.W, this);
            _keyBoardHook.HotKeyPressed += _keyBoardHook_HotKeyPressed;

            _downloadTimer.Tick += _downloadTimer_Tick;
            _downloadTimer.Interval = TimeSpan.FromMinutes(10);
            Settings settings = Settings.Default;

            lblVersion.Text = lblVersion.Text + " " + Util.GetAppVersion();

            if (settings.AutoUpdate == true)
                _downloadTimer.Start();

            Title = Title + " " + Util.GetAppVersion();

            ShowHideProviders();

            int? intVersion = DatabaseServices.Upgrade();

            if (intVersion != null)
                new MessageBoxYesNo(((App)Application.Current).LoadedLanguageResourceDictionary["DBUpgradeSucess"] + intVersion.ToString(), false, false).ShowDialog();

            _backgroundCount.RunWorkerAsync();

            lstResults.DataContext = WallPaperServices.GetIncludedFolders();
            IList resolutions = ResolutionServices.GetResolutions();

            if (resolutions != null)
            {
                foreach (Resolution resolution in resolutions)
                {
                    CheckBox chkResolution = new CheckBox();
                    chkResolution.Content = resolution.Name;
                    chkResolution.IsChecked = resolution.Enabled;
                    chkResolution.Margin = new Thickness(5, 0, 0, 0);

                    wrpResolutions.Children.Add(chkResolution);

                }
            }

            chkBing.IsChecked = settings.Bing;
            chkInterfaceLIFT.IsChecked = settings.InterfaceLIFT;
            chkRandomizer.IsChecked = settings.Randomizer;
            chkreWalls.IsChecked = settings.reWalls;
            chkSkinsBe.IsChecked = settings.SkinsBe;
            chkwallBase.IsChecked = settings.wallBase;
            chkGoodFon.IsChecked = settings.GoodFon;

            #region Preferences
            cboRefreshUnit.DataContext = Enum.GetValues(typeof(Units));
            cboUpdateUnits.DataContext = Enum.GetValues(typeof(UpdateUnits));

            chkAutoStart.IsChecked = settings.AutoSart;
            if (settings.AutoUpdate == true)
            {
                chkAutoUpdate.IsChecked = true;
                txtUpdateIntervall.IsEnabled = true;
                cboUpdateUnits.IsEnabled = true;
                lblAutoDownload.IsEnabled = true;
            }
            else
            {
                chkAutoUpdate.IsChecked = false;
                txtUpdateIntervall.IsEnabled = false;
                cboUpdateUnits.IsEnabled = false;
                lblAutoDownload.IsEnabled = false;

            }

            txtRefreshTime.Text = settings.RefreshIntervall.ToString(CultureInfo.InvariantCulture);

            if (string.IsNullOrWhiteSpace(settings.RefreshUnit) == false)
                cboRefreshUnit.SelectedValue = Enum.Parse(typeof(Units), settings.RefreshUnit, false);
            else
                cboRefreshUnit.SelectedValue = Units.Minutes;

            txtUpdateIntervall.Text = settings.UpdateIntervall.ToString(CultureInfo.InvariantCulture);
            if (string.IsNullOrWhiteSpace(settings.UpdateUnit) == false)
                cboUpdateUnits.SelectedValue = Enum.Parse(typeof(UpdateUnits), settings.UpdateUnit, false);
            else
                cboUpdateUnits.SelectedValue = UpdateUnits.Days;

            if (string.IsNullOrWhiteSpace(settings.WallPapersPath))
                txtFolder.Text = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            else
                txtFolder.Text = settings.WallPapersPath;

            GboUseProxy.IsChecked = settings.UseProxy;
            EnableControl(settings.UseProxy);

            TxtIp.Text = settings.ProxyIp;
            TxtLogin.Text = settings.ProxyLogin;
            TxtPort.Text = settings.ProxyPort;
            TxtPwd.Text = settings.ProxyPwd;
            #endregion

        }

        void _keyBoardHook_HotKeyPressed(KeyboardHook obj)
        {
            ChangeWallpaper();
        }


        void _downloadTimer_Tick(object sender, EventArgs e)
        {
            Settings settings = Settings.Default;
            TimeSpan elasped = DateTime.Now.Subtract(settings.LastUpdate);

            if (elasped > Util.GetDurationUpdate(settings.UpdateIntervall, (UpdateUnits)Enum.Parse(typeof(UpdateUnits), settings.UpdateUnit, false)))
                DownloadImages();
        }

        void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(((App)Application.Current).Ip))
                    ((App)Application.Current).Ip = DatabaseServices.GetIp();

                _objNewVersion = NewsService.CheckVersion();

                if (_objNewVersion == null)
                    _news = NewsService.GetLastNews(Settings.Default.LastMessage);


                Util.NotifyEvent("Start");
            }
            catch (Exception ex)
            {
                Util.LogException(ex);
            }
        }

        void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (_objNewVersion != null)
            {
                string strContent = HTMLConverter.htmltoxamlconverter.ConvertHtmlToXaml(((TextSyndicationContent)_objNewVersion.Content).Text, true);

                FlowDocument objDoc = (FlowDocument)XamlReader.Parse(strContent);
                newVersionViewer objViewer = new newVersionViewer(_objNewVersion.Title.Text, objDoc, _objNewVersion.Links[0].Uri) { Owner = this };
                objViewer.Show();
            }


            if (_news != null && _objNewVersion == null)
            {
                if (string.IsNullOrWhiteSpace(_news.Ip) || _news.Ip == ((App)Application.Current).Ip)
                {
                    NewsViewer newsViewer = new NewsViewer();
                    newsViewer.DataContext = _news;
                    newsViewer.ShowDialog();
                }

                Settings.Default.LastMessage = _news.Id.ToString(CultureInfo.InvariantCulture);
                Settings.Default.Save();

            }
        }
        private void _backgroundCount_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                int count = DatabaseServices.GetCount();
                if (DatabaseServices.GetDonate() == false && count >= 10)
                {
                    _showDonateMessage = true;
                    Util.NotifyEvent("Count" + count.ToString(CultureInfo.InvariantCulture));
                    count = 0;
                }
                count += 1;
                DatabaseServices.UpdateCount(count);
            }
            catch (Exception ex)
            {
                Util.LogException(ex);
            }
        }

        void _backgroundCount_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (_showDonateMessage == true)
            {
                new DonatePage().Show();
                _showDonateMessage = false;
            }
        }

        private void cmdDonate_Click(object sender, RoutedEventArgs e)
        {
            Process.Start(@"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4UB72VRPLLZ8G");
            DatabaseServices.UpdateDonate();
        }

        private void CatchException(Exception ex)
        {
            Task.Factory.StartNew(() => Util.LogException(ex));
            new MessageBoxYesNo(ex.Message, false, true).ShowDialog();
        }

        private void MainPage_SourceInitialized(object sender, EventArgs e)
        {
            Visibility = Visibility.Hidden;
        }

        private void OpenApp(object sender, ExecutedRoutedEventArgs e)
        {
            ShowMain();
        }

        private void ctxOpenApp_Click(object sender, RoutedEventArgs e)
        {
            ShowMain();
        }

        private void ShowMain()
        {
            Show();
            Activate();
            WindowState = _currentWindowState;
        }

        private void MainPage_StateChanged(object sender, EventArgs e)
        {
            if (WindowState == WindowState.Minimized)
                Hide();
            else
                _currentWindowState = WindowState;
        }

        private void ctxChangeWallpaper_Click(object sender, RoutedEventArgs e)
        {
            ChangeWallpaper();
        }

        private void ChangeWallpaper()
        {
            try
            {
                bool changed = false;
                while (changed == false)
                    changed = Util.ChangeWallPaper(WallPaperServices.GetRandomWallpaper());
            }
            catch (Exception ex)
            {
                CatchException(ex);
            }
        }

        private void ctxExcludeCurrent_Click(object sender, RoutedEventArgs e)
        {
            Settings settings = Settings.Default;
            WallPaperServices.addExcludeWallPaper(settings.CurrentWallPaper);
            ChangeWallpaper();
        }

        private void ctxDeleteCurrent_Click(object sender, RoutedEventArgs e)
        {
            Settings settings = Settings.Default;
            File.Delete(settings.CurrentWallPaper);
            ChangeWallpaper();
        }

        private void ctxShowCurrent_Click(object sender, RoutedEventArgs e)
        {
            Settings settings = Settings.Default;
            Process.Start(settings.CurrentWallPaper);
        }

        private void ctxClose_Click(object sender, RoutedEventArgs e)
        {
            _isClose = true;
            _keyBoardHook = null;
            Close();
        }

        private void MainPage_Closing(object sender, CancelEventArgs e)
        {
            if (_isClose == false)
            {
                e.Cancel = true;
                Hide();
            }
            else
                Util.NotifyEvent("Stop");
        }
        private void ShowHideProviders()
        {
            Settings settings = Settings.Default;

            if (settings.Bing == false)
                Bing.Visibility = Visibility.Collapsed;
            else
                Bing.Visibility = Visibility.Visible;

            if (settings.GoodFon == false)
                GoodFon.Visibility = Visibility.Collapsed;
            else
                GoodFon.Visibility = Visibility.Visible;

            if (settings.InterfaceLIFT == false)
                InterfaceLIFT.Visibility = Visibility.Collapsed;
            else
                InterfaceLIFT.Visibility = Visibility.Visible;

            if (settings.Randomizer == false)
                Randomizer.Visibility = Visibility.Collapsed;
            else
                Randomizer.Visibility = Visibility.Visible;

            if (settings.reWalls == false)
                reWalls.Visibility = Visibility.Collapsed;
            else
                reWalls.Visibility = Visibility.Visible;

            if (settings.SkinsBe == false)
                SkinsBe.Visibility = Visibility.Collapsed;
            else
                SkinsBe.Visibility = Visibility.Visible;

            if (settings.wallBase == false)
                wallBase.Visibility = Visibility.Collapsed;
            else
                wallBase.Visibility = Visibility.Visible;
        }

        private void ctxDownload_Click(object sender, RoutedEventArgs e)
        {
            DownloadImages();
        }

        private void DownloadImages()
        {
            Settings settings = Settings.Default;
            settings.LastUpdate = DateTime.Now;
            settings.Save();

            foreach (UcProvider item in mainStack.Children)
            {
                if (item.Visibility == Visibility.Visible)
                    item.Update();
            }
        }

        private void hypMail_Click(object sender, RoutedEventArgs e)
        {
            Hyperlink objLink = e.OriginalSource as Hyperlink;
            if (objLink != null) Process.Start(objLink.NavigateUri.ToString());
        }
        #region ManageIncludedFolder
        private void Add_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                System.Windows.Forms.FolderBrowserDialog objFolderBrowser = new System.Windows.Forms.FolderBrowserDialog();
                if (objFolderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    WallPaperServices.AddIncludeFolder(objFolderBrowser.SelectedPath);
                    lstResults.DataContext = WallPaperServices.GetIncludedFolders();
                }

            }
            catch (Exception ex)
            {
                CatchException(ex);
            }
        }

        private void Remove_Click(object sender, RoutedEventArgs e)
        {
            foreach (string item in lstResults.SelectedItems)
                WallPaperServices.DeleteIncludedFolder(item);

            lstResults.DataContext = WallPaperServices.GetIncludedFolders();
        }
        #endregion
        #region Preferences
        private void useProxy_Click(object sender, RoutedEventArgs e)
        {
            EnableControl(GboUseProxy.IsChecked != null && (bool)GboUseProxy.IsChecked);
        }
        private void EnableControl(bool isChecked)
        {
            TxtIp.IsEnabled = isChecked;
            TxtLogin.IsEnabled = isChecked;
            TxtPort.IsEnabled = isChecked;
            TxtPwd.IsEnabled = isChecked;
        }
        private void chkAutoUpdate_Checked(object sender, RoutedEventArgs e)
        {
            txtUpdateIntervall.IsEnabled = true;
            cboUpdateUnits.IsEnabled = true;
            lblAutoDownload.IsEnabled = true;
        }

        private void chkAutoUpdate_Unchecked(object sender, RoutedEventArgs e)
        {
            txtUpdateIntervall.IsEnabled = false;
            cboUpdateUnits.IsEnabled = false;
            lblAutoDownload.IsEnabled = false;
        }
        private void cmdBrowseFolder_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog objDialog = new System.Windows.Forms.FolderBrowserDialog();
            objDialog.RootFolder = Environment.SpecialFolder.MyComputer;

            if (objDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (string.IsNullOrEmpty(objDialog.SelectedPath) == false)
                    txtFolder.Text = objDialog.SelectedPath;
            }
        }
        #endregion

        private void ApplyRes_Click(object sender, RoutedEventArgs e)
        {
            IList resolutions = ResolutionServices.GetResolutions();

            foreach (Resolution resolution in resolutions)
            {
                foreach (CheckBox checkbox in wrpResolutions.Children)
                {
                    if (resolution.Name == checkbox.Content.ToString())
                    {
                        if (checkbox.IsChecked != null)
                            resolution.Enabled = (bool)checkbox.IsChecked;
                        break;
                    }
                }
            }
            ResolutionServices.UpdateResolutions(resolutions);
        }

        private void ApplySites_Click(object sender, RoutedEventArgs e)
        {
            Settings settings = Settings.Default;

            if (chkBing.IsChecked != null)
                settings.Bing = (bool)chkBing.IsChecked;

            if (chkInterfaceLIFT.IsChecked != null)
                settings.InterfaceLIFT = (bool)chkInterfaceLIFT.IsChecked;

            if (chkRandomizer.IsChecked != null)
                settings.Randomizer = (bool)chkRandomizer.IsChecked;

            if (chkreWalls.IsChecked != null)
                settings.reWalls = (bool)chkreWalls.IsChecked;

            if (chkSkinsBe.IsChecked != null)
                settings.SkinsBe = (bool)chkSkinsBe.IsChecked;

            if (chkwallBase.IsChecked != null)
                settings.wallBase = (bool)chkwallBase.IsChecked;

            if (chkGoodFon.IsChecked != null)
                settings.GoodFon = (bool)chkGoodFon.IsChecked;

            settings.Save();
        }

        private void ApplyPreferences_Click(object sender, RoutedEventArgs e)
        {
            Settings settings = Settings.Default;

            if (chkAutoStart.IsChecked != null) 
                settings.AutoSart = (bool)chkAutoStart.IsChecked;

            settings.RefreshUnit = cboRefreshUnit.Text;
            settings.UpdateUnit = cboUpdateUnits.Text;
            settings.WallPapersPath = txtFolder.Text;
            settings.Save();

            if (chkAutoStart.IsChecked == true)
                Util.AddToStartup(StartUpKeyName, Assembly.GetExecutingAssembly().Location);
            else
                Util.RemoveToStartup(StartUpKeyName);

        }

        private void ApplyAutoUpdate_Click(object sender, RoutedEventArgs e)
        {
            Settings settings = Settings.Default;

            if (chkAutoUpdate.IsChecked != null)
                settings.AutoUpdate = (bool)chkAutoUpdate.IsChecked;

            int time;
            if (int.TryParse(txtRefreshTime.Text, out time) == true)
                settings.RefreshIntervall = time;
            else
                settings.RefreshIntervall = 0;

            if (int.TryParse(txtUpdateIntervall.Text, out time) == true)
                settings.UpdateIntervall = time;
            else
                settings.UpdateIntervall = 0;

            DispatcherTimer timer = ((App)Application.Current).Timer;

            if (settings.RefreshIntervall > 0)
            {
                timer.Stop();
                timer.Interval = Util.GetDuration(settings.RefreshIntervall, (Units)Enum.Parse(typeof(Units), settings.RefreshUnit, false));
                timer.Start();
            }
            else
                timer.Stop();

            settings.Save();

            if (settings.AutoUpdate == true)
            {
                if (_downloadTimer.IsEnabled == false)
                    _downloadTimer.Start();
            }
            else
            {
                if (_downloadTimer.IsEnabled == true)
                    _downloadTimer.Stop();
            }


        }

        private void ApplyProxy_Click(object sender, RoutedEventArgs e)
        {
            Settings settings = Settings.Default;

            if (GboUseProxy.IsChecked != null)
                settings.UseProxy = (bool)GboUseProxy.IsChecked;
            settings.ProxyIp = TxtIp.Text;
            settings.ProxyLogin = TxtLogin.Text;
            settings.ProxyPort = TxtPort.Text;
            settings.ProxyPwd = TxtPwd.Text;

            settings.Save();
        }
    }
}
